<?php

class MySocket {

// room is the room number (gid or lobby).
// inputtype is an enum of [Input_ChooseOne, Input_ChooseMany, Input_Reorder].
// params is an array of alternativs to choose from.
// min & max are the minimum and maximum values of the length of the chosen alternatives array.
// extraparams is reserved for future use.
// screen is the message to print to the screen.
// name is the player to send message to. null means current player.
// async true does not stop the game. useful for many requesing response from many players.
    public static function GetUserReply($room, $inputtype, $params, $min, $max, $extraparams, $screen, $name = null, $async = false) {

        $db = DBUtils::Create();

        $name = $room->getCurrentPlayerName($name);
        $oldPhase = $room->getPhase($name);


        $options = "";
        foreach ($params as $p) {
            $options .= $p->getValue() . "|";
        }

        $id = $room->getId();


        $db->setInput($id, $name, $inputtype, $options, $min, $max, $extraparams, $screen);
        $room->save();
        //important to set player input, only after there is an input, to prevent strange behaviours in this critical section
        $room->setPhase(Phase_Input, $name);
        alertPlayer($name);

        if (!$async) {

            //KIRIL: i changed the loop to this one, it checks the stage of the person and not the 
            //existance of reply in db. it seems better that way
            //NOTE: that requres a change in the commands orders in setUserOutput
            $cur_phase = $room->getPhase($name);
            set_time_limit(INPUT_TIMEOUT);
            while ($cur_phase != Phase_Output) {
                session_write_close();
                usleep(200000);
                session_start();
                $cur_phase = $room->getPhase($name);
            }
            $res = $db->getOutput($id, $name);
			DEBUG("--- Output ---", false);
			DEBUG("current phase: ".$cur_phase, false);
            set_time_limit(30);

            //setting to old phase just after we got the output.
            $room->setPhase($oldPhase, $name);
			DEBUG("setting phase: ".$oldPhase, false);
            $res = preg_split('/\|/', $res, -1, PREG_SPLIT_NO_EMPTY);

            self::deleteInputOutput($id, $name);
			DEBUG("deleting input output", false);
            return $res;
        } else {
            return true;
        }
    }

    function GetUserReplyBuyBeforeAction($cardName, $room, $inputtype, $params, $min, $max, $extraparams, $screen, $name = null, $async = false) {
        $db = DBUtils::Create();

        $name = $room->getCurrentPlayerName($name);
        $oldPhase = $room->getPhase($name);


        $options = "";
        foreach ($params as $p) {
            $options .= $p->getValue() . "|";
        }

        $id = $room->getId();
        $db->setInput($id, $name, $inputtype, $options, $min, $max, $extraparams, $screen);
        $room->save();
        if ($cardName == "BlackMarket")
            $room->setPhase(Phase_BlackMarketPayment, $name);
        elseif ($cardName == "DigitalStore") {
            $room->setPhase(Phase_DigitalStorePayment, $name);
        } else {
            throw new Exception;
        }
        alertPlayer($name);



        if (!$async) {

            //KIRIL: i changed the loop to this one, it checks the stage of the person and not the 
            //existance of reply in db. it seems better that way
            //NOTE: that requres a change in the commands orders in setUserOutput
            $cur_phase = $room->getPhase($name);
            set_time_limit(INPUT_TIMEOUT);
            while ($cur_phase != Phase_Output) {
                session_write_close();
                usleep(200000);
                session_start();
                $cur_phase = $room->getPhase($name);
            }
            $res = $db->getOutput($id, $name);

            /*
              $res = null;
              $res = $db->getOutput($id, $name);
              set_time_limit(INPUT_TIMEOUT);
              while ($res === null) {
              session_write_close();
              usleep(200000);
              session_start();
              $res = $db->getOutput($id, $name);
              }
             */
            set_time_limit(30);
            $room->setPhase($oldPhase, $name);

            $res = preg_split('/\|/', $res, -1, PREG_SPLIT_NO_EMPTY);

            self::deleteInputOutput($id, $name);

            return $res;
        } else {
            return true;
        }
    }

    public static function getUsersReplies($room) {

        $db = DBUtils::Create();

        $allPlayersNames = $room->getPlayersNames();
        $activePlayersNames = array();
        foreach ($allPlayersNames as $name) {
            $player_phase = $room->getPhase($name);
            if ($player_phase == Phase_Input || $player_phase == Phase_Output)
                $activePlayersNames[] = $name;
        }

        $id = $room->getId();
        $res = array();
        $results_expected = sizeof($activePlayersNames);
        set_time_limit(INPUT_TIMEOUT);
        while (true) {
            foreach ($activePlayersNames as $name) {
                if (!array_key_exists($name, $res)) {
                    $cur_phase = $room->getPhase($name);
                    if ($cur_phase == Phase_Output) {
                        $output = $db->getOutput($id, $name);
                        $res[$name] = preg_split('/\|/', $output, -1, PREG_SPLIT_NO_EMPTY);

                        //and we clean, putting the user in sleep state
                        $room->setPhase(Phase_Sleep, $name);
                        self::deleteInputOutput($id, $name);
                    }
                }
            }
            if (sizeof($res) == $results_expected)
                break;
            session_write_close();
            usleep(200000);
            session_start();
        }
        set_time_limit(30);
        return $res;
    }

    function deleteInputOutput($id, $name) {
        $db = DBUtils::Create();
        $db->deleteInputOutput($id, $name);
    }

    function setUserOutput($id, $name, $output_params) {
        $db = DBUtils::Create();
        $room = null;
        if ($id > 0)
            $room = loadgame();
        else
            $room = loadLobby();

        //before the loop change in getuserreply and getuserreplybefore actions those are the lines
        //$room->setPhase(Phase_Sleep, $name);
        //$db->setOutput($id, $name, $output_params);
        //after the change, those are the lines:
        $db->setOutput($id, $name, $output_params);
        $room->setPhase(Phase_Output, $name);
    }

    function getInput($room, $name) {
        $db = DBUtils::Create();
        $phase = $room->getPhase($name);
        if ($phase != Phase_Input && $phase != Phase_BlackMarketPayment && $phase != Phase_DigitalStorePayment && $phase != Phase_DigitalStoreBuy)
            return null;
        $res = $db->getInput($room->getId(), $name);
        return $res;
    }

}

?>